/**
 * 鼠标经过提示信息类（tip）
 */

( function( j )
{
	// 全局参数
	j.tips = {
		opacity: 0.95, // tips 浮动层的透明度
		color: '#333', // 字体颜色
		background: "#ffe", // 背景颜色
		"min-width": "50px", // 最小宽度
		"max-width": "450px", // 最大宽度
		radius: "4px", // 边框圆角值
		follow: false, // 是否跟随鼠标移动
		style: null, // 附加样式集合，格式 {color:"#333", background:"#ffe"}
		regists: [], // 已经注册的对象集合

		has: function( tar )
		{
			var id = $( tar ).attr( "id" );

			if( !empty( id ) && j.tips.regists.indexOf( id ) != -1 )
				return true;

			return false;
		}
	};

	j.Tips_Cls = function( tar, content )
	{

		// Public methods
		// ---------------------------------------------------------------------------

		var pub = this;
		var _target = tar; // 显示对象
		var _content = content; // 显示内容

		pub.regist = function()
		{
			// 缓存ID，以便于检测重复注册
			var id = $( _target ).attr( "id" );

			if( empty( id ) )
			{
				id = hash( 12 );
				$( _target ).attr( "id", id );
			}

			j.tips.regists.push( id );

			// tar is HTML element : j( tar ).text()
			// 鼠标事件触发显示和隐藏
			j( _target ).mouseover( _mouseover );
			j( _target ).mouseleave( _mouseleave );

			// 跟随移动
			if( j.tips.follow )
			{
				j( _target ).mousemove( _mousemove );
			}
		};

		pub.unregist = function()
		{
			j( _target ).unbind( "mouseover", _mouseover );
			j( _target ).unbind( "mouseleave", _mouseleave );
			j( _target ).unbind( "mousemove", _mousemove );
		};

		// Private methods
		// ---------------------------------------------------------------------------

		// 显示 tips
		function _show()
		{
			_hide();

			// 添加载体
			j( "body" ).append( '<div id="TIPS_CONTAINER" onselectstart="return false"></div>' );

			// 样式设置
			var radius = j.tips.radius;
			j( "#TIPS_CONTAINER" ).css( {
				position: "absolute", // 相对于页面绝对定位（因只有在看得见的元素才能触发 tips 事件）
				border: "1px solid #999",
				"font-size": "14px",
				color: j.tips.color,
				background: j.tips.background,
				zIndex: 99999,
				padding: "5px 10px 5px 10px",
				margin: 0,
				overflow: "hidden",
				"line-height": "22px",
				"word-break": "break-all",
				"-moz-border-radius": radius,
				"-khtml-border-radius": radius,
				"-webkit-border-radius": radius,
				"border-radius": radius,
				"box-shadow": "1px 1px 3px #ccc",
				"min-width": j.tips[ "min-width" ], // 最小宽度
				"max-width": j.tips[ "max-width" ], // 最大宽度
				"-moz-user-select": "none",
			} );

			// 透明度
			j( "#TIPS_CONTAINER" ).alpha( j.tips.opacity );

			// 附加样式
			if( !empty( j.tips.style ) )
				j( "#TIPS_CONTAINER" ).css( j.tips.style );

			// TIPS 内容
			j( "#TIPS_CONTAINER" ).html( _content );

			// 首次移动原点，得到实际宽度
			j( "#TIPS_CONTAINER" ).move( 0, 0 );
		}

		// 隐藏 tips
		function _hide()
		{
			j( "#TIPS_CONTAINER" ).remove();
		}

		// 重新调整位置
		function _reposition( pageX, pageY )
		{
			var tar = j( _target );

			var offsetX = tar.position().left;
			var offsetY = tar.position().top;

			var winWidth = j( window ).width();
			var winHeight = j( window ).height();
			var scrollLeft = j( window ).scrollLeft();
			var scrollTop = j( window ).scrollTop();

			var tipsWidth = j( "#TIPS_CONTAINER" ).outerWidth();
			var tipsHeight = j( "#TIPS_CONTAINER" ).outerHeight();

			if( !j.tips.follow )
			{
				if( offsetX + tipsWidth > winWidth + scrollLeft )
				{
					offsetX = winWidth + scrollLeft - tipsWidth - 5;
				}

				// 默认绝对定位到对象下方
				offsetY = offsetY + tar.outerHeight() + 5;

				// 若下方无法显示下所有内容，则反向显示在对象顶部
				if( offsetY + tipsHeight > winHeight + scrollTop )
				{
					offsetY = tar.position().top - tipsHeight - 5;
				}
			}
			else
			{
				// 跟随鼠标移动
				offsetX = pageX + 10;
				offsetY = pageY + 10;

				if( offsetX + tipsWidth > winWidth + scrollLeft )
				{
					offsetX = winWidth + scrollLeft - tipsWidth - 5;
				}
			}

			j( "#TIPS_CONTAINER" ).move( offsetX, offsetY );
		}

		// Event methods
		// ---------------------------------------------------------------------------

		function _mouseover( e )
		{
			// 显示
			_show();

			// 首次定位
			_reposition();
		}

		function _mousemove( e )
		{
			if( j.tips.follow )
				_reposition( e.pageX, e.pageY );
		}

		function _mouseleave( e )
		{
			_hide();
		}
	};

	// extend methods
	// ---------------------------------------------------------------------------

	/**
	 * 注册 Tips
	 * 
	 * @param content 需要显示的 tips 内容
	 * @param autoRegist 是否自动注册相关的事件（默认：true）
	 * @return 该对象相关的 Tips 实例
	 *         <p>
	 *         若设置 autoRegist 为 false，需要手动调用 tip.regist() 来注册相关事件。
	 *         </p>
	 */
	j.fn.tips = function( content, autoRegist )
	{
		if( j.tips.has( this ) )
			return null;

		tip = new j.Tips_Cls( this, content );

		if( autoRegist != false )
			autoRegist = true;

		if( autoRegist )
		{
			tip.regist();
		}

		return tip;
	};
} )( jQuery );

// 默认在页面初始化时，将所有包含 title 属性的对象替换成 tips 显示
$( document ).ready( function( e )
{
	set_tips();
} );

/**
 * 将指定容器内的包含 title 属性的对象替换为 tips 显示
 * 
 * @param container 缺省为 body
 */
function set_tips( container )
{
	if( empty( container ) )
		container = "body";

	$( container ).find( "[title]" ).each( function( idx )
	{
		var title = $( this ).attr( "title" );

		if( !empty( title ) )
		{
			$( this ).attr( "title", "" );
			$( this ).tips( title );
		}
	} );
}
